package iteratorbind.entity;


import iteratorbind.base.BaseMenuComponent;
import java.util.ArrayList;
import java.util.Iterator;

/**
 * 菜单对象 子节点
 * 可以持有菜单项对象(叶节点)
 * 还可以持有其他的菜单对象(子节点)
 * @author yaojianfeng
 */

public class MenuChildNode extends BaseMenuComponent {
    /**
     * 菜单可以有任意数目的孩子
     * 这些孩子都必须属于BaseMenuComponent
     * 我们使用内部的ArrayList记录它们
     */
    ArrayList<BaseMenuComponent> menuComponents = new ArrayList<>();
    String name;
    String description;

    /**
     * 这和我们之前的实现不一样,我们将给每个菜单一个名字和一个描述
     * 以前每个菜单的类名称就是此菜单的名字
     * @param name 名字
     * @param description 描述
     */
    public MenuChildNode(String name, String description) {
        this.name = name;
        this.description = description;
    }

    /**
     * 添加菜单(菜单项)
     * @param component 菜单节点
     */
    @Override
    public void add(BaseMenuComponent component) {
        menuComponents.add(component);
    }

    /**
     * 删除菜单(菜单项)
     * @param component 菜单节点
     */
    @Override
    public void remove(BaseMenuComponent component) {
        menuComponents.remove(component);
    }
    /**
     * 获得菜单(菜单项)对象
     * @param i 菜单节点位置索引
     */
    @Override
    public BaseMenuComponent getChild(int i) {
        return menuComponents.get(i);
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public String getDescription() {
        return description;
    }

    /**
     * 利用迭代器 用它遍历所有菜单组件
     * 在遍历过程中,可能遇到其他菜单 或者是遇到菜单项
     * 由于菜单和菜单项都实现了print()
     * 所以在迭代过程中我们只要调用print()即可
     * NOTICE: 在遍历期间,如果遇到另一个菜单对象,它的print()方法会开始另一个遍历,依次类推
     */
    @Override
    public void print() {
        System.out.print("\n" + getName());
        System.out.println("," + getDescription());
        System.out.println("--------------------------------" );
        Iterator<BaseMenuComponent> iterator = menuComponents.iterator();
        while (iterator.hasNext()){
            BaseMenuComponent next = iterator.next();
            next.print();
        }
    }

    /**
     * 获取迭代器
     * 子类需要实现这个方法
     * 这意味着对一个组合调用该方法 将会应用于该组合的所有节点
     *CompositeIterator:这个迭代器知道如何遍历任何组合
     * 我们将当前组合的迭代器传入它的构造器
     * @return 迭代器
     */
    @Override
    public Iterator getIterator() {
        return new CompositeIterator(menuComponents.iterator());
    }

    /**
     * 这个是自己实现的打印方法
     * @return 输出字符串
     */
    @Override
    public String toString(){
        StringBuilder stringBuilder = new StringBuilder();
        for (BaseMenuComponent next : menuComponents) {
            stringBuilder.append(next.toString());
        }
        return stringBuilder.toString();
    }

}
